<?php
namespace app\index\controller;
use think\Db;
use think\Validate;
use think\Exception;
use think\facade\Cache;
use think\facade\Env;
use think\Queue;
use think\Log;

class Index
{	
	private $cache;
    private  $handler;
	public function __construct() {
		$this->cache = Cache::init();
		$this->handler = $this->cache->handler();
	}

    public function index()
    {
    	$data = input('post.');

        unset($data['balance']);
        unset($data['credit']);
        
        // $blacklist = [
        //     "18124198164","13401363108","17688552009","15089352898","13602940094","13346643336","13181351655","18301123028","13598020751","13014568187",
        //     "13428733909","17337991130","13275342497"
        // ];

        $rule = [
            'mobile' => 'require|number|length:11',
            'password' => 'require|length:6,32',
        ];

        $msg = [
            'mobile.require' => '手机号必须',
            'mobile.length' => '手机号为11位数字',
            'mobile.number' => '手机号为11位数字',
            'password.require' => '密码必须',
            'password.length' => '密码为6-12位之间',
        ];

        //验证数据是否合法
        $mobile = isset($data['mobile']) ? $data['mobile'] : '';

        $validate = new Validate($rule, $msg);
        $result = $validate->check($data);

        if (!$result) {
            var_dump($validate->getError());
            die;
        }
        
        // if(in_array($mobile,$blacklist)) {
        //     var_dump('该手机号已注册了');    // 黑名单
        //     die;
        // }
        
        // 判断手机号是否在集合中
        $is_existe = $this->handler->sIsMember("register:mobile",$mobile);
        if(!$is_existe) {
            $this->handler->sAdd("register:mobile",$mobile);
        }else {
            //Log::write('---压力测试'.date("Y-m-d h:i:s").'---手机号已存在');
            var_dump('手机号已存在');    // 用户已存在
            die;
        }

        // 查询手机号码是否已注册
        $user = db('user')->field('mobile')->where('mobile', $mobile)->find();
        if ($user) {
            //Log::write('---压力测试'.date("Y-m-d h:i:s").'---手机号注册了');
            var_dump('手机号已注册');    // 用户已存在
            die;
        }       

        // 用户不存在注册
        // $data['id']          = getNewUserid();
        $data['no'] = date("Ymdhis").rand(100, 999);
        $data['avatar'] = 'https://rumcdn-1255484416.cos.ap-chengdu.myqcloud.com/img/d_h.png';
        $data['password'] = md5($data['password']);
        $randomNickname = date("Ymdhis").rand(100, 999);         
        $data['nickname'] = 'rm_' . $randomNickname;
        $data['create_time'] = time();
        $data['type'] = 1;
        
        /***是否存在邀请人的跑步钱进号***/
        if(isset($data['pbqj_no']) && !empty($data['pbqj_no'])) {
            $inviter = db('user')->field('id')->where(["no"=>$data['pbqj_no']])->find();
            if($inviter) {
                $data['inviter_id'] = $inviter['id'];
            }
        }
        /***是否存在邀请人的跑步钱进号***/
        unset($data['pbqj_no']);
        $userid = db('user')->insertGetId($data);

        if ($userid) {
        /******************加入消息队列异步处理后续操作*******************/

            // 1.当前任务将由哪个类来负责处理。 
            // 当轮到该任务时，系统将生成一个该类的实例，并调用其 fire 方法
            $jobHandlerClassName  = 'app\index\job\JobUser'; 
            // 2.当前任务归属的队列名称，如果为新队列，会自动创建
            $jobQueueName         = "userJobQueue"; 
            // 3.当前任务所需的业务数据 . 不能为 resource 类型，其他类型最终将转化为json形式的字符串
            // ( jobData 为对象时，需要在先在此处手动序列化，否则只存储其public属性的键值对)
            //$jobData              = ['ts' => time(), 'bizId' => uniqid() , 'a' => 1];
            $jobData              = ['userid'=>$userid,'time'=>time(),'mobile'=>$mobile,'inviterid'=>(isset($data['inviter_id']) ? $data['inviter_id'] : 0)];
            // 4.将该任务推送到消息队列，等待对应的消费者去执行
            $isPushed = Queue::push($jobHandlerClassName , $jobData , $jobQueueName);    
            // database 驱动时，返回值为 1|false  ;   redis 驱动时，返回值为 随机字符串|false
            if($isPushed !== false) { 
            	var_dump('加入队列成功');
            	die;
                //Log::write('-----------加入消息队列成功-----------');
                //echo date('Y-m-d H:i:s') . " a new Hello Job is Pushed to the MQ"."<br>";
            }else{
            	var_dump('加入消息队列');
            	die;
                //Log::write('-----------加入消息队列失败-----------');
                //echo 'Oops, something went wrong.';
            }
        /******************加入消息队列异步处理后续操作*******************/

            $res['id'] = $userid;
            $res['no'] = $data['no'];

            // // token处理类
            // $accessToken = new AccessToken();
            // $accessToken = $accessToken->getToken($userid);

            // if (empty($accessToken)) {
            //     //Log::write('---压力测试'.date("Y-m-d h:i:s").'---秘钥生成失败');
            //     var_dump('秘钥生成失败');
            // } else {
            //     $res['user_token'] = $accessToken;
            // }

            // if (method_exists(\chat\User::class, 'getToken')) {
            //     $chat_token = \chat\User::getToken($res['id'], $data['nickname'], $data['avatar']);
            //     if (!$chat_token) {
            //         //Log::write('---压力测试'.date("Y-m-d h:i:s").'---聊天秘钥生成失败');
            //         var_dump('聊天秘钥生成失败');
            //     } else {
            //         $res['chat_token'] = $chat_token;
            //     }
            // } else {
            //     $res['chat_token'] = '';
            // }
            
            //Log::write('---压力测试'.date("Y-m-d h:i:s").'---注册成功');
            var_dump($res);
            die;
        } else {
            //Log::write('---压力测试'.date("Y-m-d h:i:s").'---数据库错误');
            $this->handler->sRem("register:mobile",$mobile);
            var_dump('数据库错误');
            die;
        }
    }

    // 测试并发量大的情况下库存超量
    public function hello($name = 'ThinkPHP5')
    {
        /**乐观锁: 对并发友好**/
        $info = Db::name('ztest')->field('count,version')->where('id',947)->find();
        $cur_ver = $info['version']+1;
        if($info['version']<$cur_ver) {
            if($info['count']>0) {
                $updata_data = [
                    "count" => $info['count']-1,
                    "version" => $cur_ver,
                ];
                $res = Db::name('ztest')->where('id',947)->update($updata_data);
            }
        }
        /**乐观锁: 对并发友好**/
        var_dump(isset($res)?$res:0);


        /**悲观锁:**/
        // $count = Db::name('ztest')->where('id',947)->lock(true)->find();
        // if($count['count']<=0) {
        //     var_dump('超卖了啊');
        //     die;
        // }
        
        // $res = 0;
        // if($count['count']>0) {

        //     $res = Db::name('ztest')->where(['id'=>947])->setDec('count',1);
        // }
        /**悲观锁:**/

        // var_dump($res);
        // die;

        // var_dump('hello fuchao');
        // die;
        // return 'hello,' . $name;
    }

}
